﻿using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Rescue_of_the_Dwarvenzombies.Scene;

namespace Rescue_of_the_Dwarvenzombies.GameStates
{
    /// <summary>
    /// The GameStateManager manages the different states, such as PlayingState and PauseState, 
    /// pushes them on a stack and pops them accordingly during the gameplay.
    /// </summary>
    /// <remarks></remarks>
    internal class GameStateManager
    {
        /// <summary>
        /// The stack of GameStates.
        /// </summary>
        private Stack<GameState> _gameStates = new Stack<GameState>();
        /// <summary>
        /// 
        /// </summary>
        protected Game Game;

        /// <summary>
        /// Initializes a new instance of the <see cref="GameStateManager"/> class.
        /// </summary>
        /// <param name="game">The game.</param>
        /// <remarks></remarks>
        public GameStateManager(Game game)
        {
            Game = game;
            //For now, set initial state to Playing state
            ChangeState(new PlayingState(game, this));
        }

        /// <summary>
        /// Changes the state.
        /// </summary>
        /// <param name="newState">The new state.</param>
        /// <remarks></remarks>
        public void ChangeState(GameState newState)
        {
            if (!ContainsState(newState))
            {
                _gameStates.Push(newState);
                ((ISceneManager)Game.Services.GetService(typeof(ISceneManager))).CurrentState = newState;
            }
            else
            {
                _gameStates.Pop();
                ((ISceneManager)Game.Services.GetService(typeof(ISceneManager))).CurrentState = CurrentState;
            }
        }

        /// <summary>
        /// Determines whether the specified new state contains state.
        /// </summary>
        /// <param name="newState">The new state.</param>
        /// <returns><c>true</c> if the specified new state contains state; otherwise, <c>false</c>.</returns>
        /// <remarks></remarks>
        public bool ContainsState(GameState newState)
        {
            return _gameStates.Contains(newState);
        }

        /// <summary>
        /// Gets the state of the current.
        /// </summary>
        /// <remarks></remarks>
        public GameState CurrentState
        {
            get { return _gameStates.Peek(); }
        }

        /// <summary>
        /// Resets the states.
        /// </summary>
        /// <remarks></remarks>
        public void ResetStates()
        {
            _gameStates.Clear();
            ChangeState(new PlayingState(Game, this));
        }
    }
}